/*******************************************************
 *			srlos timer driver
 *@filename hard_timer.c
 *@author	bloceanc
 *@date		08/14/2010
 *@commen	this file manager the hardware timer
 ******************************************************/
#include "hw_portdef.h"
#include "int.h"

long long ll_tick_count;
extern void int_enable_interrupt(int_source type, irq_service service);
extern void task_schedule_normal(void);
extern void int_request_reset(int_source type);

/***
 * Conmments:
 *		At S3C2440, there are 5 timers. we use timer 1 for scheudle, timer 2 for app, timer3 for DMA.
 * schedule timer we defined it 20ms, perscalur=0, divid=1/2, PLCK=50M, timer count value = 25000!
 */

/* 
 *	Timer 1 Interrupt service
 */
void hw_timer_1_service(void)
{
	ll_tick_count++;
	int_request_reset(INT_TIMER1);	// 不能放在调度函数之后，因为SRLOS的机制，允许再调度后跳转到任意位置，这样字的话，该调度函数
									// 该调度函数很可能永远不会返回（例如，再fork之后，线程会直接跳到fork函数后面的继续运行，而
									// 永远不会在从这个函数返回！因而，需要提前清掉中断请求！）
	
	// every 32ms we schedule task.
	if(!(ll_tick_count&0x1f))
	{
		task_schedule_normal();
	}
}

/*
 * initialize timer, we use three timers. on for schedule, another for application timer.
 *		the third timer used for DMA
 */
void hw_timer_initialize(void)
{
	R_TCFG0 = 0x0;
	R_TCFG1 = 0x400000;
	R_TCNTB1 = 25000;
	R_TCMPB1 = 0x0;

	R_TCON = 0x6ee60e;
	
	// set service 
	int_enable_interrupt(INT_TIMER1,hw_timer_1_service);

	// enable timer 1
	R_TCON = 0x6ee90e;
}

/*
 * get system tick count
 */
long long get_tick_count(void)
{
	return ll_tick_count;
}
